home *** CD-ROM | disk | FTP | other *** search
/ X User Tools / X User Tools (O'Reilly and Associates)(1994).ISO / sources / libxpm / libxpm34.gz / libxpm34 / xpm-3.4 / lib / XpmCrDataFrI.c < prev    next >
C/C++ Source or Header  |  1994-03-14  |  8KB  |  307 lines

  1. /* Copyright 1989-94 GROUPE BULL -- See license conditions in file COPYRIGHT */
  2. /*****************************************************************************\
  3. * XpmCrDataFI.c:                                                              *
  4. *                                                                             *
  5. *  XPM library                                                                *
  6. *  Scan an image and possibly its mask and create an XPM array                *
  7. *                                                                             *
  8. *  Developed by Arnaud Le Hors                                                *
  9. \*****************************************************************************/
  10.  
  11. #include "xpmP.h"
  12. #ifdef VMS
  13. #include "sys$library:string.h"
  14. #else
  15. #if defined(SYSV) || defined(SVR4)
  16. #include <string.h>
  17. #else
  18. #include <strings.h>
  19. #endif
  20. #endif
  21.  
  22. LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size,
  23.               XpmColor *colors, unsigned int ncolors,
  24.               unsigned int cpp));
  25.  
  26. LFUNC(CreatePixels, void, (char **dataptr, unsigned int width,
  27.                unsigned int height, unsigned int cpp,
  28.                unsigned int *pixels, XpmColor *colors));
  29.  
  30. LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num,
  31.                   unsigned int *ext_size,
  32.                   unsigned int *ext_nlines));
  33.  
  34. LFUNC(CreateExtensions, void, (char **dataptr, unsigned int offset,
  35.                    XpmExtension *ext, unsigned int num,
  36.                    unsigned int ext_nlines));
  37.  
  38. int
  39. XpmCreateDataFromImage(display, data_return, image, shapeimage, attributes)
  40.     Display *display;
  41.     char ***data_return;
  42.     XImage *image;
  43.     XImage *shapeimage;
  44.     XpmAttributes *attributes;
  45. {
  46.     XpmImage xpmimage;
  47.     XpmInfo info;
  48.     int ErrorStatus;
  49.  
  50.     /* initialize return value */
  51.     if (data_return)
  52.     *data_return = NULL;
  53.  
  54.     /* create an XpmImage from the image */
  55.     ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
  56.                          &xpmimage, attributes);
  57.     if (ErrorStatus != XpmSuccess)
  58.     return (ErrorStatus);
  59.  
  60.     /* create the data from the XpmImage */
  61.     if (attributes) {
  62.     xpmSetInfo(&info, attributes);
  63.     ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, &info);
  64.     } else
  65.     ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, NULL);
  66.  
  67.     /* free the XpmImage */
  68.     XpmFreeXpmImage(&xpmimage);
  69.  
  70.     return (ErrorStatus);
  71. }
  72.  
  73. #undef RETURN
  74. #define RETURN(status) \
  75. { \
  76.     if (header) { \
  77.     for (l = 0; l < header_nlines; l++) \
  78.         if (header[l]) \
  79.         XpmFree(header[l]); \
  80.         XpmFree(header); \
  81.     } \
  82.     return(status); \
  83. }
  84.  
  85. int
  86. XpmCreateDataFromXpmImage(data_return, image, info)
  87.     char ***data_return;
  88.     XpmImage *image;
  89.     XpmInfo *info;
  90. {
  91.     /* calculation variables */
  92.     int ErrorStatus;
  93.     char buf[BUFSIZ];
  94.     char **header = NULL, **data, **sptr, **sptr2, *s;
  95.     unsigned int header_size, header_nlines;
  96.     unsigned int data_size, data_nlines;
  97.     unsigned int extensions = 0, ext_size = 0, ext_nlines = 0;
  98.     unsigned int offset, l, n;
  99.  
  100.     *data_return = NULL;
  101.  
  102.     extensions = info && (info->valuemask & XpmExtensions)
  103.     && info->nextensions;
  104.  
  105.     /* compute the number of extensions lines and size */
  106.     if (extensions)
  107.     CountExtensions(info->extensions, info->nextensions,
  108.             &ext_size, &ext_nlines);
  109.  
  110.     /*
  111.      * alloc a temporary array of char pointer for the header section which
  112.      * is the hints line + the color table lines
  113.      */
  114.     header_nlines = 1 + image->ncolors;
  115.     header_size = sizeof(char *) * header_nlines;
  116.     header = (char **) XpmCalloc(header_size, sizeof(char *));
  117.     if (!header)
  118.     return (XpmNoMemory);
  119.  
  120.     /* print the hints line */
  121.     s = buf;
  122.     sprintf(s, "%d %d %d %d", image->width, image->height,
  123.         image->ncolors, image->cpp);
  124.     s += strlen(s);
  125.  
  126.     if (info && (info->valuemask & XpmHotspot)) {
  127.     sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot);
  128.     s += strlen(s);
  129.     }
  130.     if (extensions)
  131.     sprintf(s, " XPMEXT");
  132.  
  133.     l = strlen(buf) + 1;
  134.     *header = (char *) XpmMalloc(l);
  135.     if (!*header)
  136.     RETURN(XpmNoMemory);
  137.     header_size += l;
  138.     strcpy(*header, buf);
  139.  
  140.     /* print colors */
  141.     ErrorStatus = CreateColors(header + 1, &header_size,
  142.                    image->colorTable, image->ncolors, image->cpp);
  143.  
  144.     if (ErrorStatus != XpmSuccess)
  145.     RETURN(ErrorStatus);
  146.  
  147.     /* now we know the size needed, alloc the data and copy the header lines */
  148.     offset = image->width * image->cpp + 1;
  149.     data_size = header_size + (image->height + ext_nlines) * sizeof(char *)
  150.     + image->height * offset + ext_size;
  151.  
  152.     data = (char **) XpmMalloc(data_size);
  153.     if (!data)
  154.     RETURN(XpmNoMemory);
  155.  
  156.     data_nlines = header_nlines + image->height + ext_nlines;
  157.     *data = (char *) (data + data_nlines);
  158.     n = image->ncolors;
  159.     for (l = 0, sptr = data, sptr2 = header; l <= n; l++, sptr++, sptr2++) {
  160.     strcpy(*sptr, *sptr2);
  161.     *(sptr + 1) = *sptr + strlen(*sptr2) + 1;
  162.     }
  163.  
  164.     /* print pixels */
  165.     data[header_nlines] = (char *) data + header_size
  166.     + (image->height + ext_nlines) * sizeof(char *);
  167.  
  168.     CreatePixels(data + header_nlines, image->width, image->height,
  169.          image->cpp, image->data, image->colorTable);
  170.  
  171.     /* print extensions */
  172.     if (extensions)
  173.     CreateExtensions(data + header_nlines + image->height - 1, offset,
  174.              info->extensions, info->nextensions,
  175.              ext_nlines);
  176.  
  177.     *data_return = data;
  178.  
  179.     RETURN(XpmSuccess);
  180. }
  181.  
  182. static int
  183. CreateColors(dataptr, data_size, colors, ncolors, cpp)
  184.     char **dataptr;
  185.     unsigned int *data_size;
  186.     XpmColor *colors;
  187.     unsigned int ncolors;
  188.     unsigned int cpp;
  189. {
  190.     char buf[BUFSIZ];
  191.     unsigned int a, key, l;
  192.     char *s, *s2;
  193.     char **defaults;
  194.  
  195.     for (a = 0; a < ncolors; a++, colors++, dataptr++) {
  196.  
  197.     defaults = (char **) colors;
  198.     strncpy(buf, *defaults++, cpp);
  199.     s = buf + cpp;
  200.  
  201.     for (key = 1; key <= NKEYS; key++, defaults++) {
  202.         if (s2 = *defaults) {
  203.         sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
  204.         s += strlen(s);
  205.         }
  206.     }
  207.     l = strlen(buf) + 1;
  208.     s = (char *) XpmMalloc(l);
  209.     if (!s)
  210.         return (XpmNoMemory);
  211.     *data_size += l;
  212.     strcpy(s, buf);
  213.     *dataptr = s;
  214.     }
  215.     return (XpmSuccess);
  216. }
  217.  
  218. static void
  219. CreatePixels(dataptr, width, height, cpp, pixels, colors)
  220.     char **dataptr;
  221.     unsigned int width;
  222.     unsigned int height;
  223.     unsigned int cpp;
  224.     unsigned int *pixels;
  225.     XpmColor *colors;
  226. {
  227.     char *s;
  228.     unsigned int x, y, h, offset;
  229.  
  230.     h = height - 1;
  231.     offset = width * cpp + 1;
  232.     for (y = 0; y < h; y++, dataptr++) {
  233.     s = *dataptr;
  234.     for (x = 0; x < width; x++, pixels++) {
  235.         strncpy(s, colors[*pixels].string, cpp);
  236.         s += cpp;
  237.     }
  238.     *s = '\0';
  239.     *(dataptr + 1) = *dataptr + offset;
  240.     }
  241.     /* duplicate some code to avoid a test in the loop */
  242.     s = *dataptr;
  243.     for (x = 0; x < width; x++, pixels++) {
  244.     strncpy(s, colors[*pixels].string, cpp);
  245.     s += cpp;
  246.     }
  247.     *s = '\0';
  248. }
  249.  
  250. static void
  251. CountExtensions(ext, num, ext_size, ext_nlines)
  252.     XpmExtension *ext;
  253.     unsigned int num;
  254.     unsigned int *ext_size;
  255.     unsigned int *ext_nlines;
  256. {
  257.     unsigned int x, y, a, size, nlines;
  258.     char **line;
  259.  
  260.     size = 0;
  261.     nlines = 0;
  262.     for (x = 0; x < num; x++, ext++) {
  263.     /* 1 for the name */
  264.     nlines += ext->nlines + 1;
  265.     /* 8 = 7 (for "XPMEXT ") + 1 (for 0) */
  266.     size += strlen(ext->name) + 8;
  267.     a = ext->nlines;
  268.     for (y = 0, line = ext->lines; y < a; y++, line++)
  269.         size += strlen(*line) + 1;
  270.     }
  271.     /* 10 and 1 are for the ending "XPMENDEXT" */
  272.     *ext_size = size + 10;
  273.     *ext_nlines = nlines + 1;
  274. }
  275.  
  276. static void
  277. CreateExtensions(dataptr, offset, ext, num, ext_nlines)
  278.     char **dataptr;
  279.     unsigned int offset;
  280.     XpmExtension *ext;
  281.     unsigned int num;
  282.     unsigned int ext_nlines;
  283. {
  284.     unsigned int x, y, a, b;
  285.     char **line;
  286.  
  287.     *(dataptr + 1) = *dataptr + offset;
  288.     dataptr++;
  289.     a = 0;
  290.     for (x = 0; x < num; x++, ext++) {
  291.     sprintf(*dataptr, "XPMEXT %s", ext->name);
  292.     a++;
  293.     if (a < ext_nlines)
  294.         *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
  295.     dataptr++;
  296.     b = ext->nlines;
  297.     for (y = 0, line = ext->lines; y < b; y++, line++) {
  298.         strcpy(*dataptr, *line);
  299.         a++;
  300.         if (a < ext_nlines)
  301.         *(dataptr + 1) = *dataptr + strlen(*line) + 1;
  302.         dataptr++;
  303.     }
  304.     }
  305.     strcpy(*dataptr, "XPMENDEXT");
  306. }
  307.